#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <queue>
using namespace std;

#define CardLength 10

char *cardArray[] = {
    "A♠",  "2♠", "3♠",  "4♠", "5♠",  "6♠", "7♠", "8♠", "9♠", "10♠", "J♠",
    "Q♠",  "K♠", "A♣",  "2♣", "3♣",  "4♣", "5♣", "6♣", "7♣", "8♣",  "9♣",
    "10♣", "J♣", "Q♣",  "K♣", "A♥",  "2♥", "3♥", "4♥", "5♥", "6♥",  "7♥",
    "8♥",  "9♥", "10♥", "J♥", "Q♥",  "K♥", "A♦", "2♦", "3♦", "4♦",  "5♦",
    "6♦",  "7♦", "8♦",  "9♦", "10♦", "J♦", "Q♦", "K♦"
    // , "Joker1", "Joker2"
};
int cardArrayLength = sizeof(cardArray) / sizeof(cardArray[0]);

// 从扑克牌中随机抽取n张牌，放入数组中
void getCard(char card[][CardLength], int n) {
    int *flag = (int *)calloc(cardArrayLength, sizeof(int));
    srand(time(NULL));
    for (int i = 0; i < n; i++) {
        int t;
        do {
            t = rand() % cardArrayLength;
        } while (flag[t]);
        flag[t] = 1;
        strcpy(card[i], cardArray[t]);
    }
    free(flag);
}

// 扑克牌撕两半，合并在一起
void tearCard(char card[][CardLength], int n) {
    for (int i = 0; i < n; i++) {
        strcpy(card[i + n], card[i]);
        strcat(card[i], "-1");
        strcat(card[i + n], "-2");
    }
}

// 从前面拿n个元素放到中间第m个元素后面
void move(char card[][CardLength], int n, int m) {
    char temp[n][CardLength];
    // 保存前n个元素
    for (int i = 0; i < n; i++) {
        strcpy(temp[i], card[i]);
    }
    // 移动m-n个元素
    int ml = m - n;
    for (int i = 0; i < ml; i++) {
        strcpy(card[i], card[i + n]);
    }
    // 把前n个元素放到m后面
    for (int i = 0; i < n; i++) {
        strcpy(card[i + ml], temp[i]);
    }
}

// 拿掉第一个张牌
void deleteFirst(char card[][CardLength], int n) {
    for (int i = 0; i < n - 1; i++) {
        strcpy(card[i], card[i + 1]);
    }
}

// 打印扑克牌
void printCard(char card[][CardLength], int n) {
    for (int i = 0; i < n; i++) {
        printf("%s ", card[i]);
    }
    printf("\n");
}

void printQueue(deque<char *> &q) {
    for (char* e : q) {
        printf("%s ", e);
    }
    printf("\n");
}

int main() {
    // 用一个二维数组保存8张牌
    char card[8][CardLength];

    printf("抽取4张牌：\n");
    getCard(card, 4);
    printCard(card, 4);
    printf("撕两半，合并在一起：\n");
    tearCard(card, 4);
    printCard(card, 8);

    printf("按照姓名字数拿牌，你的姓名有几个字：");
    int n, m;
    scanf("%d", &n);
    printf("把%d张牌放到最后面：", n);
    move(card, n, 8);
    printCard(card, 8);

    printf("最上面的3张扑克牌插到中间，输入插入的位置[4-7]：");
    scanf("%d", &m);
    printf("上面的3张扑克牌插到第%d张的后面：", m);
    move(card, 3, m);
    printCard(card, 8);

    // 把第一张牌藏起来
    char first[CardLength];
    strcpy(first, card[0]);
    deleteFirst(card, 8);
    printf("把第一张牌 %s 藏起来：", first);
    printCard(card, 7);

    // 根据地域分布拿牌
    printf("你的地域是：南方输入1，北方输入2，南北方输入3：");
    scanf("%d", &n);
    printf("插到第几张的后面[4-6]：");
    scanf("%d", &m);
    move(card, n, m);
    printCard(card, 7);

    // 男生仍1张，女生仍2张
    printf("你的性别是：男生输入1，女生输入2：");
    scanf("%d", &n);
    int left = 7 - n;
    deleteFirst(card, 7);
    if (n == 2) {
        deleteFirst(card, 6);
    }
    printCard(card, left);

    // 见证奇迹的时刻
    printf("见证奇迹的时刻\n");
    for (int i = 1; i <= 7; i++) {
        printf("%d：", i);
        move(card, 1, left);
        printCard(card, left);
    }

    // 好运留下来，烦恼丢出去
    deque<char *> q;
    for (int i = 0; i < left; i++) {
        q.push_back(card[i]);
    }

    printf("好运留下来，烦恼丢出去：\n");
    n = 0;
    while (q.size() > 1) {
        char *e;
        printf("第%d次\n", ++n);
        printf("好运留下来\n");
        e = q.front();
        q.pop_front();
        q.push_back(e);
        printf("烦恼丢出去\n");
        e = q.front();
        q.pop_front();
        printQueue(q);
    }
    printf("最后留下来的牌是：%s\n", q.front());
    return 0;
}